package com.ws.demo.mergeOrderedLinkedList;

import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class MergeOrderedLinkedListDemo {


    /**
     * 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
     */
    /**
     * 递归的方式
     * 如果 l1 或者 l2 一开始就是空链表 ，那么没有任何操作需要合并，所以我们只需要返回非空链表。
     * 否则，我们要判断 l1 和 l2 哪一个链表的头节点的值更小，然后递归地决定下一个添加到结果里的节点。
     * 如果两个链表有一个为空，递归结束。
     */
//    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//        if (l1 == null) {
//            return l2;
//        } else if (l2 == null) {
//            return l1;
//        } else if (l1.val < l2.val) {
//            l1.next = mergeTwoLists(l1.next, l2);
//            return l1;
//        } else {
//            l2.next = mergeTwoLists(l1, l2.next);
//            return l2;
//        }
//    }

    /**
     * 迭代的方式
     * 我们可以用迭代的方法来实现上述算法。当 l1 和 l2 都不是空链表时，
     * 判断 l1 和 l2 哪一个链表的头节点的值更小，将较小值的节点添加到结果里，
     * 当一个节点被添加到结果里之后，将对应链表中的节点向后移一位。
     */
    public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode preached = new ListNode(-1);

        ListNode prev = preached;//定义 变量接收
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                prev.next = l1; //设置指针
                l1 = l1.next;//下一层
            } else {
                prev.next = l2;//设置指针
                l2 = l2.next;//下一层
            }
            prev = prev.next;//指针 下一层
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完，我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 == null ? l2 : l1;

        return preached.next;
    }


    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1, new ListNode(1, new ListNode(2, new ListNode(3))));
        ListNode listNode2 = new ListNode(2, new ListNode(3, new ListNode(3, new ListNode(4))));

        System.out.println("mergeTwoLists(listNode1, listNode2) = " + JSONObject.toJSONString(mergeTwoLists(listNode1, listNode2), true));
    }


}

class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public ListNode getNext() {
        return next;
    }

    public void setNext(ListNode next) {
        this.next = next;
    }
}